import Array._
import scala.util.Random

class Chessboard{
    var mat = ofDim[String](3,3)
    var notOccupy = List.tabulate(9)(n => n)

    /*    y
        0 1 2
      x 3 4 5
        6 7 8
    */
    def getResidul():Int = {
        var choose:Int = Random.shuffle(notOccupy).take(1)(0)
        notOccupy = notOccupy.filter(n => n!=choose)
        choose
    }

    def move(x:Int,y:Int,id:String){
         mat(x)(y) = id
         if (notOccupy == Nil){
             endGame()
         }
    }

    def endGame(){
        println("Game Finished")
        showmat()
        winner()
    }

    def showmat(){
        for (i <- 0 until mat.length){
            println(mat(i).mkString("  "))
        }
    }


    def winner(){
        var res = List[String]()
        mat.foreach(x => res = x.reduceLeft(_+_) +: res)

        var tam = transpose(mat)
        tam.foreach(x => res = x.reduceLeft(_+_) +: res)

        res = (tam(0)(0) + tam(1)(1) + tam(2)(2)) +: res
        res = (tam(0)(2) + tam(1)(1) + tam(2)(0)) +: res

        if (res.exists(x => x == "AAA")){
            println("Winner is playerA")
        }else if(res.exists(x => x == "BBB")){
            println("Winner is playerB")
        }else{
            println("No winner")
        }
    }

    def transpose( m: Array[Array[String]] ): Array[Array[String]] = {
        ( for { c <- m(0).indices } yield { m.map( _(c)) } ).toArray
    }
    //在for中依次遍历m(0)的列数，存入c，然后在yield中，通过map方法对m中每一行取当前第c个元素，将m中的每一行的第c个元素取出，并通过yield返回，组合成一个Array作为转置后的第c行。
    //use zip
}

class Player(cb:Chessboard){
    def play(playerId:String){
        var choose = cb.getResidul()
        cb.move(choose / 3 ,choose % 3,playerId)
    }
}

object Test {
    def main(args: Array[String]) {
        val cb = new Chessboard()
        val playerA = new Player(cb)
        val playerB = new Player(cb)

        var flag = true
        while (flag){
                try{
                    playerA.play("A")
                    playerB.play("B")
                }catch{
                    case ex: IndexOutOfBoundsException=>{
                        flag = false
                    }
                }
        }
    }
}